package com.salon.client.tabItems;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.allen_sauer.gwt.dnd.client.DragContext;
import com.allen_sauer.gwt.dnd.client.DragEndEvent;
import com.allen_sauer.gwt.dnd.client.DragHandler;
import com.allen_sauer.gwt.dnd.client.DragStartEvent;
import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.allen_sauer.gwt.dnd.client.VetoDragException;
import com.allen_sauer.gwt.dnd.client.drop.AbsolutePositionDropController;
import com.allen_sauer.gwt.dnd.client.drop.SimpleDropController;
import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.IconAlign;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.WindowEvent;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Html;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.salon.client.GreetingServiceAsync;
import com.salon.client.MainView;
import com.salon.client.Salon;
import com.salon.client.beans.MasterBean;
import com.salon.client.beans.ProcedureBean;
import com.salon.client.beans.WorkDayBean;
import com.salon.client.widgets.ProcedureDialog;
import com.salon.client.widgets.panels.IncomeMaterialsPanel;
import com.salon.client.widgets.panels.ProcedurePanel;

public class SchedulerTabItemPanel extends ContentPanel {
	
	private static PickupDragController dragController = new PickupDragController(RootPanel.get(), false);

	private static DragHandler dragHandler = new DragHandler() {

		public void onDragEnd(DragEndEvent event) {
			System.out.println("Drag End");
		}

		public void onDragStart(DragStartEvent event) {
			System.out.println("Drag Start");
		}

		public void onPreviewDragEnd(DragEndEvent event)
				throws VetoDragException {

			if ((event.getSource() == null) || (event.getContext() == null) ||
					(event.getContext().dropController == null) ||
					(event.getContext().dropController.getDropTarget() == null)) {
				System.out.println("Drag Preview Drop missing required elements");
				throw new VetoDragException();
			}
			System.out.println("Drag Preview Drop of "+event.getSource().getClass().getName()+
					" on "+event.getContext().dropController.getDropTarget().getClass().getName());

			Object source = event.getSource();
			Object dest = event.getContext().dropController.getDropTarget();
			
			/*if ((!(source instanceof Icon)) || (!(dest instanceof Target))) {
				System.out.println("Source is not Icon or Dest is not Target");
				throw new VetoDragException();
			}
			
			if (!((Target)dest).dropOn((Icon) source))
				throw new VetoDragException();*/
			Info.display("1", "2");
		}

		public void onPreviewDragStart(DragStartEvent event)
				throws VetoDragException {
			System.out.println("Drag Preview Start");
		}
	};
	
	static {
		dragController.addDragHandler(dragHandler);
		dragController.setBehaviorDragProxy(false);
	}
	
	private ToolBar toolbar = new ToolBar();
	private FlexTable table = null;
	private Date curentDate = new Date();
	private List<Date> dates = new ArrayList<Date>();
	private List<MasterBean> masters = new ArrayList<MasterBean>();
	private int offset = 0;
	private final String styleCell = "salon-ProcedureCell";
	private final String styleCellPlan = "salon-ProcedureCellPlan";
	private ProcedurePanel panel = null;
	private Map<Date, Map<MasterBean, ProcedureBean>> procedures = null;
	public SchedulerTabItemPanel() {
		setScrollMode(Scroll.AUTO);
		setBodyBorder(false);
		setHeading("Расписание процедур11111");
		setButtonAlign(HorizontalAlignment.CENTER);
		//setLayout(new FitLayout());
		toolbar.setBorders(true);
		toolbar.setAlignment(HorizontalAlignment.CENTER);
		setBottomComponent(toolbar);
		
		initComponents();
	}
	
	protected void initComponents() {
		Button prev = new Button("Предыдущий день");
		prev.setIcon(IconHelper.createStyle("salon-prev"));
		prev.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				offset = -1;
				reInitSchedulerTable();
			}
			
		});
		
		toolbar.add(prev);
		
		Button refresh = new Button("Обновить");
		refresh.setIcon(IconHelper.createStyle("brit-refresh-button"));
		refresh.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				reInitSchedulerTable();		
			}
			
		});
		toolbar.add(refresh);
		
		Button next = new Button("Следующий день");
		next.setIconAlign(IconAlign.RIGHT);
		next.setIcon(IconHelper.createStyle("salon-next"));
		next.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				offset = 1;
				reInitSchedulerTable();
			}
			
		});
		toolbar.add(next);
		
		table = new FlexTable();
		table.setWidth("70%");
		//table.setHeight("500px");
		table.setStyleName("salon-Cell");
		table.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Cell cell = table.getCellForEvent(event);
				selectCell(cell.getCellIndex(), cell.getRowIndex());
			}
			
		});
		reInitSchedulerTable();
		add(table);
		
	}
	
	public void reInitSchedulerTable() {
		((GreetingServiceAsync) Registry.get(Salon.SERVICE)).
		getProceduresForDay(curentDate, offset, new AsyncCallback<Map<Date,Map<MasterBean,ProcedureBean>>>() {

			@Override
			public void onFailure(Throwable caught) {
				Info.display("Не удалось получить", "календарь процедур");
				
			}

			@Override
			public void onSuccess(
					Map<Date, Map<MasterBean, ProcedureBean>> result) {
				procedures = result;
				offset = 0;
				clearTable();
				reIninLists(result);
				
				String cellsize = 100/masters.size() + "%";
				for (int i = 0; i < dates.size(); i++) {
					if (i == 0) {
						setHeading(DateTimeFormat.getFormat("dd.MM.yyyy").format(dates.get(0)));
						curentDate = dates.get(0);
						table.setWidget(0, 0, new HTML(""));
						table.getCellFormatter().setWidth(0, 0, "40px");
						for (int j = 0; j < masters.size(); j++) {
							table.setHTML(i, j + 1, masters.get(j).getMasterName());
							table.getCellFormatter().setHorizontalAlignment(i, j + 1, HasHorizontalAlignment.ALIGN_CENTER);
							table.getCellFormatter().setWidth(i, j + 1, cellsize);
							table.getCellFormatter().setHeight(i, j + 1, "40px");
						}
					}
					table.setHTML(i + 1, 0, getStringDate(dates.get(i)));
					table.getCellFormatter().setWidth(i + 1, 0, "20px");
					table.getCellFormatter().setHeight(i + 1, 0, "40px");
					for (int j = 0; j < masters.size(); j++) {
						ProcedureBean bean = result.get(dates.get(i)).get(masters.get(j));
						if (bean == null) {
							table.setHTML(i + 1, j + 1, "&nbsp");
						}
						else {
							//table.setHTML(i + 1, j + 1, bean.getDecs());
							HTML html = new HTML(bean.getDecs());
							html.sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS | Event.ONMOUSEWHEEL
							          | Event.ONLOAD);
							dragController.makeDraggable(html);
							
							SimpleDropController dropController = new SimpleDropController(html) {
								@Override
								public void onMove(DragContext context) {
									super.onMove(context);
								}
							};
							
							dragController.registerDropController(dropController);
							
							table.setWidget(i + 1, j + 1, html);
							table.getCellFormatter().addStyleName(i + 1, j + 1, bean.getStatus() ? styleCell : styleCellPlan);
						}
						
						table.getCellFormatter().setWidth(i + 1, j + 1, cellsize);
						table.getCellFormatter().setHeight(i + 1, j + 1, "40px");
					}
				}
			}
		});
	}
	
	private void reIninLists(Map<Date, Map<MasterBean, ProcedureBean>> result) {
		dates.clear();
		masters.clear();
		
		Date date = null;
		
		Iterator<Date> iter = result.keySet().iterator();
		while(iter.hasNext()) {
			date = iter.next();
			dates.add(date);
		}
		if (date != null) {
			Iterator<MasterBean> masterIter = result.get(date).keySet().iterator();
			while(masterIter.hasNext()) {
				masters.add(masterIter.next());
			}
		}
		Collections.sort(dates);
		Collections.sort(masters);
	}
	
	private String getStringDate(Date date) {
		DateTimeFormat format = DateTimeFormat.getFormat("HH:mm");
		return format.format(date);
	}
	
	private void clearTable() {

		for (int i = table.getRowCount() - 1; i >= 0; i --) {
			table.removeRow(i);
		}
	}
	
	private void selectCell(int col, int row) {
		MasterBean bean = masters.get(col - 1);
		Date date = dates.get(row - 1);
		
		Info.display(bean.getNiceName(), date.toString());
		
		/*PopupPanel dlg = new PopupPanel();
		dlg.setAnimationEnabled(true);
		dlg.setSize("500px", "300px");
		ProcedurePanel panel = new ProcedurePanel();
		dlg.add(panel);
		dlg.center();*/
		/*ProcedureDialog dlg = new ProcedureDialog(null);
		dlg.show();
		dlg.addListener(Events.Hide, new Listener<WindowEvent>() {
		      public void handleEvent(WindowEvent be) {
		    	  reInitSchedulerTable();
		      }
		    });*/
		if (panel == null) {
			panel = new ProcedurePanel(this);
		}
		ProcedureBean proc = null;
		if (procedures != null) {
			if (procedures.get(date) != null) {
				if (procedures.get(date).get(bean) != null) {
					proc = procedures.get(date).get(bean);
				}
			}
		}
		panel.setData(proc, bean, date);
	}
}
